<?php

//定义数据库前缀
defined("TABLE_PREFIX") ? "" : define("TABLE_PREFIX", "function_");

global $db_link; //声明全局链接
//打开链接
function db_connect()
{
    global $db_link;
    if (empty($db_link)) {
        $db_link = mysqli_connect("localhost", "root", "root", "student"); //如果没有链接 放一个链接进入全局变量
    }
    return $db_link;
}
//设置编码函数
function set_db_charset()
{
    //局部变量没有被定义 出现警告
    global $db_link;
    static $set_db_charset = 0; //默认是没有设置编码的 静态变量 会存储上次函数调用后处理的结果
    if (empty($db_link)) {
        $db_link = db_connect();
    }
    if ($set_db_charset < 1) {
        mysqli_query($db_link, "set names utf8"); //设定编码
        $set_db_charset = 1;
    }
    return $db_link;
}
//底层操作数据查询函数
function db_query($sql = '')
{
    global $db_link; //声明使用全局变量
    $db_link = set_db_charset(); //这一步是为了拿到已经设置编码的数据库连接
    $query_result = $db_link->query($sql); //查询操作结果
    return $query_result; //返回查询结果
}

//查询所欲执行函数
function db_select($sql = '')
{
    $query_result = db_query($sql); //发送查询
    $data_list = $query_result->fetch_all(MYSQLI_ASSOC); //返回结果集
    return $data_list; //返回列表
}
//插入一条执行函数
function db_insert($sql = '')
{
    global $db_link; //声明使用全局变量
    $query_result = db_query($sql); //发送查询
    if ($query_result) {
        return mysqli_insert_id($db_link); //插入成功返回自增id
    }
    return false;
}
//更新数据库执行函数
function db_update($sql = '')
{
    return db_query($sql); //发送查询
}
//删除数据执行函数
function db_delete($sql = '')
{
    return db_query($sql); //发送查询
}
//查询数据库只查询一条
function db_find($sql = '')
{
    $query_result = db_query($sql); //发送查询
    $data_list = $query_result->fetch_assoc(); //返回结果集
    return $data_list; //返回列表
}
//查询数据库的统计数量
function db_count($sql = '')
{
    $data_list = db_find($sql); //得到查询结果
    $data_list = array_shift(array_values($data_list));
    return $data_list; //返回列表
}

//返回数据库操作表
function table_name($table_name = '', $prefix = TABLE_PREFIX)
{
    return "`" . $prefix . $table_name . "`";
}
//根据table name 生成查询SQL 查询全部
function create_select_sql($table_name = '', $where = '', $fields = "*", $prefix = '')
{
    if ($where != "") {
        $where = " where " . $where;
    }
    $sql = "select " . $fields . " from " . table_name($table_name, $prefix) . " " . $where;
    return $sql;
}
//根据table name 生成查询SQL 查询一条
function create_find_sql($table_name = '', $where = '', $fields = "*", $prefix = '')
{
    return create_select_sql($table_name, $where, $fields, $prefix) . " limit 1";
}
//根据table name 生成删除SQL
function create_delete_sql($table_name = '', $where = '', $prefix = '')
{
    if ($where != "") {
        $where = " where " . $where;
    }
    $sql = "delete from " . table_name($table_name, $prefix) . " " . $where;
    return $sql;
}
//根据table name 生成插入SQL
function create_insert_sql($table_name = '', $insert_data = [], $prefix = '')
{
    //目标SQL  insert into table_name (id ,name click_num) values(null,'user_tese',3);
    //目标SQL  insert into table_name set id=null,name='user_test',click_num=3
    $sql = "insert into " . table_name($table_name, $prefix) . " " . create_data_condition_sql($insert_data);
    return $sql;
}
//根据table name 生成更新SQL
function create_update_sql($table_name = '', $update_data = [], $where = "", $prefix = '')
{
    //目标SQL update table_name set name='test_user_update',click_num=5 where id=10
    $where = create_where_condition_sql($where); //对where 函数处理
    if ($where != "") {
        $where = " where " . $where;
    }
    $sql = "update " . table_name($table_name, $prefix) . " " . create_data_condition_sql($update_data) . " " . $where;
    return $sql;
}

//将保存的数组转换为SQL
function create_data_condition_sql($data = [])
{
    return "set " . create_array_to_string_sql($data); //调用函数把保存数据转为字符串
}
//将更新的条件数组转换为SQL
function create_where_condition_sql($where = [])
{
    return create_array_to_string_sql($where, "and"); //调用函数把条件数组转为字符串
}
//将数组转字符串SQL
function create_array_to_string_sql($data = [], $flag = ",")
{
    $string = ""; //初始化字符串
    if (is_array($data) && !empty($data)) {
        //只有确定是数组情况下才开始转换
        foreach ($data as $k => $v) {
            $string .= "`$k`='{$v}'" . $flag; //拼接数组为键值链接的SQL形式
        }
        return rtrim($string, $flag); //去掉最右边的逗号
    }
    return $data; //不是数组或者数位为空 则不转换
}

function create_limit($page_num = 10, $total_num = 0)
{
    $now_page = isset($_GET['p']) ? intval($_GET['p']) : 1; //得到当前页面
    $total_page = ceil($total_num / $page_num);
    $now_page = min($total_page, $now_page); //保证分页的正确性
    $now_page = max(1, $now_page); //保证分页的正确性
    $start = ($now_page - 1) * $page_num;
    $string = " limit {$start},{$page_num}";
    return $string; //返回limit
}
//45个 每页展示10个  5

function page($total_count = 0, $page_num = 10)
{
    $url = get_page_url(); //获取URL
    if ($total_count <= $page_num) {
        return "";
    } //因为不够分页
    $total_num = ceil($total_count / $page_num); //总的页数
    $now_page = isset($_GET['p']) ? intval($_GET['p']) : 1; //得到当前页面
    $now_page = max($now_page, 1); //保证页面数大于等于1
    $now_page = min($now_page, $total_num); //保证页面数不能大于总数目
    $page_string = "<div class='pagelist'>";
    if ($now_page != 1) {
        $page_string .= "<a href='$url&p=1'>首页</a>";
        $page_string .= "<a href='$url&p=" . ($now_page - 1) . "'>上一页</a>";
    }

    $start_position = $now_page - 3;
    if ($start_position < 1) {
        $start_position = 1;
    }
    $end_position = $now_page + 3;
    if ($end_position > $total_num) {
        $end_position = $total_num;
    }
    for ($i = $start_position; $i <= $end_position; $i++) {
        if ($i != $now_page) {
            $page_string .= "<a href='$url&p=" . ($i) . "'>" . $i . "</a>";
        } else {
            $page_string .= "<span class='current'>" . $i . "</span>";
        }
    }
    if ($now_page != $total_num) {
        $page_string .= "<a href='$url&p=" . ($now_page + 1) . "'>下一页</a>";
        $page_string .= "<a href='$url&p=" . ($total_num) . "'>尾页</a>";
    }
    $page_string .= "</div>";
    return $page_string;
}

function get_page_url()
{
    //act=student&p=3&id=34
    $query_string = $_SERVER['QUERY_STRING'];
    $query_string = explode("&", $query_string);
    $key_list = [];
    $string = "";
    foreach ($query_string as $v) {
        $info = explode("=", $v);
        $key_list[$info[0]] = $info[1];
    }
    if (isset($key_list['p'])) {
        unset($key_list['p']);
    }
    foreach ($key_list as $k => $v) {
        $string .= "$k={$v}&";
    }
    $string = rtrim($string, "&");
    $script_name = $_SERVER['SCRIPT_NAME'];
    $script_name = explode("/", $script_name);
    $script_name = array_pop($script_name);
    return $script_name . "?" . $string; //返回URL
}
//创建一个能够生成select标签的函数
function create_select_label($data = [], $attr = [], $selected = "")
{
    $string = $items = $check = ""; //初始化字符串
    $items = create_item_html($attr); //调用生成item属性
    $string .= "<select {$items}>"; //拼接string 形成 select
    foreach ($data as $k => $v) {
        $check = create_check_flag("selected", $k, $selected); //查看是否选中了
        $string .= "<option value='{$k}' {$check}>" . $v . "</option>"; //拼接option
    }
    $string .= "</select>"; //拼接结束标签
    return $string; //返回字符串
}
//创建一个能够生成radio标签的函数
function create_radio_label($data = [], $attr = [], $selected = "")
{
    $string = $items = $check = ""; //初始化字符串
    $items = create_item_html($attr); //调用生成item属性
    foreach ($data as $k => $v) {
        $check = create_check_flag("checked", $k, $selected); //查看是否选中了
        $string .= "<label><input {$items} type='radio' value='{$k}' {$check}>" . $v . "</label>"; //拼接option
    }
    return $string; //返回字符串
}
//将数组转换为html的属性值
function create_item_html($attr = [])
{
    $items = ""; //初始化字符串
    if (!empty($attr)) {
        foreach ($attr as $k => $v) {
            $items .= " {$k}=" . '"' . $v . '" '; //拼接item属性值
        }
    }
    return $items; //返回结果
}
//返回是否选中的标识
function create_check_flag($type = "selected", $now_value, $check_value = "")
{
    $string = $check_value == $now_value ? ($type . '="' . $type . '"') : ""; //查看是否选中了
    return $string;
}
function safe($data = [], $key = "", $default = "")
{
    return isset($data[$key]) ? $data[$key] : $default;
}
//通过get接收
function get($key = "", $default = "")
{
    return param($key, __FUNCTION__, $default); //调用param
}
//通过POST接收
function post($key = "", $default = "")
{
    return param($key, __FUNCTION__, $default); //调用param
}
//获取表单提交的参数
function param($key = "", $method = "get", $default = "")
{
    $value = null; //初始化返回值
    if ($method == "get") {
        $data = $_GET; //从GET中获取
    } elseif ($method == "post") {
        $data = $_POST; //从POST中获取
    } else {
        return null; //方式不对
    }
    $info = debug_backtrace(); //获取被调用的信息
    array_shift($info); //弹出自己被调用
    $use_function = array_shift($info);
    if (is_null($use_function)) {
        die("不可用直接调用" . __FUNCTION__ . "方法");
    }
    if (!in_array($use_function['function'], array("get", "post"))) {
        die($use_function['function'] . "方法不在" . __FUNCTION__ . "方法的白名单中");
    }
    if ($key !== "") {
        $value = isset($data[$key]) ? $data[$key] : null; //通过get获取参数

        if ((is_null($value) || $value === "") && $default !== "") {
            $value = $default; //赋默认值
        }
    }
    return $value; //返回获取的值
}

function all($key_array = [], $method = "get")
{
    if (is_string($key_array)) {
        $key_array = array_filter(explode(",", $key_array)); //如果是字符串 字符串转数组
    }
    foreach ($key_array as $k => $v) {
        if (is_numeric($k)) {
            $k = $v;
            $v = ""; //如果没有给默认值 键被值替换 并给值为默认空
        }
        $data[$k] = $method($k, $v); //循环接收参数 并给默认值
    }
    return $data; //返回数组
}
/*
 * 加密字符串
 * **/
function encode($string = "")
{
    $string = md5(sha1(md5(sha1(sha1(md5($string))))));
    return $string; //返回加密后的
}
/*
 * 跳转函数
 * **/
function js_redirect($url = "index.php", $msg = "")
{
    if ($msg) {
        echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
        echo "<script>alert('$msg');window.location.href='$url';</script>";
        exit;
    } else {
        header("location:$url");
    }
}

function my_array_unshift($array = [], $array2 = [])
{
    $list  = [];
    foreach ($array2 as $key => $value) {
        $list[$key] = $value;
    }
    foreach ($array as $key => $value) {
        $list[$key] = $value;
    }
    return $list;
}

if (!function_exists("array_column")) {
    function array_column($array = [], $value = "", $key = "")
    {
        $new_array = [];
        foreach ($array as $k => $v) {
            if ($key != '') {
                $new_array[$v[$key]] = $v[$value];
            } else {
                $new_array[] = $v[$value];
            }
        }
        return $new_array;
    }
}

//封装一个函数来检测是否使用缓存
function use_cache()
{
    return CACHE === true; //是否使用缓存
}

function set_cache($key, $value)
{
    $key_name = md5($key);
    $path = CACHE_PATH . $key_name . ".php";
    if ($value === null) {
        @unlink($path);
    } //为null删除缓存
    file_put_contents($path, "<?php die();?>" . serialize($value));
}

function get_cache($key)
{
    $info = null;
    $key_name = md5($key);
    $path = CACHE_PATH . $key_name . ".php";
    if (file_exists($path)) {
        $info = substr(file_get_contents($path), 14); //去掉头部的die()
        $info = unserialize($info);
    }
    return $info;
}

//=================钩子函数===========================
/*
 * 封装的通用获取分页列表
 * **/
function hock_base_list($table_name = "")
{
    $data = [];
    $total_count = db_count("select count(id) from {$table_name}");
    $data['page'] = page($total_count, $page_num = 5);
    $sql = create_select_sql($table_name) . create_limit(5, $total_count);
    $data['list'] = db_select($sql); //查询数据
    return $data;
}
/*
 * 封装的通用获取一条记录(默认通过主键id)
 * **/
function hock_base_info($table_name = '', $pk_value = "", $pk = "id")
{
    $key = $table_name . "_" . $pk . "_" . $pk_value; //设置缓存键
    $info = db_find(create_find_sql($table_name, "$pk=" . $pk_value)); //查到信息
    return $info; //返回信息
}

function hock_base_del($table_name = '', $pk_value = [], $pk = "id")
{
    $pk_where = implode(",", $pk_value);
    $sql = create_delete_sql($table_name, "$pk in (" . $pk_where . ")");
    return db_delete($sql);
}

function hock_clear_cache()
{
    $path = CACHE_PATH;
    $list = scandir($path); //取出文件列表
    foreach ($list as $v) {
        if ($v == "." || $v == "..") {
            continue;
        }
        @unlink($path . $v);
    }
    js_redirect("index.php", "缓存清除完毕");
}

function get_all_course_hash($clear = false)
{
    $key = "course_list"; //设置缓存键
    if (use_cache()) {
        if (!$clear) {
            //使用缓存
            $list = get_cache($key); //获取缓存
            if ($list) {
                return $list;
            }
        }
    }
    $list = array_column(db_select(create_select_sql("course")), "course_name", "id");
    set_cache($key, $list); //设置缓存
    return $list; //返回信息
}

function get_all_teacher_hash($clear = false)
{
    $key = "teacher_list"; //设置缓存键
    if (use_cache()) {
        if (!$clear) {
            //使用缓存
            $list = get_cache($key); //获取缓存
            if ($list) {
                return $list;
            }
        }
    }
    $list = array_column(db_select(create_select_sql("teacher")), "teacher_name", "id");
    set_cache($key, $list); //设置缓存
    return $list; //返回信息
}

function get_all_class_hash($clear = false)
{
    $key = "class_list"; //设置缓存键
    if (use_cache()) {
        if (!$clear) {
            //使用缓存
            $list = get_cache($key); //获取缓存
            if ($list) {
                return $list;
            }
        }
    }
    $list = array_column(db_select(create_select_sql("class")), "class_name", "id");
    set_cache($key, $list); //设置缓存
    return $list; //返回信息
}

function get_all_year_hash()
{
    $list = [];
    for ($i = 1980; $i <= 2050; $i++) { 
        $list[$i] = $i;
    }
    return $list;
}

function hock_student()
{
    $data = [];
    $data = hock_base_list("student");
    $data['class'] = get_all_class_hash(); //得到班级列表的键值数组
    return $data;
}

function hock_student_edit()
{
    $data = [];
    $id = intval(get("id")) + 0;
    if ($id > 0) {
        $data['info'] = hock_base_info('student', $id);
    } else {
        //新增
        $data['info']['class_id'] = 0;
    }
    $class_list = my_array_unshift(get_all_class_hash(), ["" => "请选择班级"]);
    $attr = array(
        "name" => "class_id",
        "class" => "input w50",
        "data-validate" => "required:请选择班级"
    );
    $data['class'] = create_select_label($class_list, $attr, $data['info']['class_id']);
    return $data;
}

function hock_student_edit_do()
{
    $data = [];
    $id = intval(post("id")) + 0;
    $post_data = all(array("stu_name" => "", "stu_no" => "", "class_id" => ""), "post");
    if ($id > 0) {
        $result = db_update(create_update_sql('student', $post_data, $where = "id={$id}", $prefix = ''));
    } else {
        $result = $id = db_insert(create_insert_sql('student', $post_data, $prefix = ''));
    }
    if ($result) {
        js_redirect("index.php?act=student", "操作成功");
    } else {
        js_redirect("index.php?act=student_edit&id={$id}", "操作失败");
    }
}

function hock_student_del()
{
    $id = get("id");
    $id = explode("-", $id);
    $p = get("p") + 0;
    $result = hock_base_del('student', $id);
    if ($result) {
        js_redirect("index.php?act=student&p={$p}", "操作成功");
    } else {
        js_redirect("index.php?act=student&p={$p}", "操作失败");
    }
}

function hock_teacher()
{
    $data = [];
    $data = hock_base_list("teacher");
    return $data;
}

function hock_teacher_edit()
{
    $data = [];
    $id = intval(get("id")) + 0;
    if ($id > 0) {
        $data['info'] = hock_base_info('teacher', $id);
    } else {
        //新增
    }
    return $data;
}

function hock_teacher_edit_do()
{
    $data = [];
    $id = intval(post("id")) + 0;
    $post_data = all(array("teacher_name" => "", "teacher_tel" => "", "teach_age" => 0), "post");
    if ($id > 0) {
        $result = db_update(create_update_sql('teacher', $post_data, $where = "id={$id}", $prefix = ''));
    } else {
        $result = $id = db_insert(create_insert_sql('teacher', $post_data, $prefix = ''));
    }
    if ($result) {
        get_all_teacher_hash(true);
        js_redirect("index.php?act=teacher", "操作成功");
    } else {
        js_redirect("index.php?act=teacher_edit&id={$id}", "操作失败");
    }
}

function hock_teacher_del()
{
    $id = get("id");
    $id = explode("-", $id);
    $p = get("p") + 0;
    $result = hock_base_del('teacher', $id);
    if ($result) {
        get_all_teacher_hash(true);
        js_redirect("index.php?act=teacher&p={$p}", "操作成功");
    } else {
        js_redirect("index.php?act=teacher&p={$p}", "操作失败");
    }
}

function hock_class()
{
    $data = [];
    $data['class'] = get_all_class_hash(); //得到班级列表的键值数组
    return $data;
}

function hock_class_edit()
{
    $data = [];
    $id = intval(get("id")) + 0;
    if ($id > 0) {
        $data['info'] = hock_base_info('class', $id);
    } else {
        //新增
    }
    return $data;
}

function hock_class_edit_do()
{
    $data = [];
    $id = intval(post("id")) + 0;
    $post_data = all(array("class_name" => ""), "post");
    if ($id > 0) {
        $result = db_update(create_update_sql('class', $post_data, $where = "id={$id}", $prefix = ''));
    } else {
        $result = $id = db_insert(create_insert_sql('class', $post_data, $prefix = ''));
    }
    if ($result) {
        get_all_class_hash(true);
        js_redirect("index.php?act=class", "操作成功");
    } else {
        js_redirect("index.php?act=class_edit&id={$id}", "操作失败");
    }
}

function hock_class_del()
{
    $id = get("id");
    $id = explode("-", $id);
    $p = get("p") + 0;
    $result = hock_base_del('class', $id);
    if ($result) {
        get_all_class_hash(true);
        js_redirect("index.php?act=class&p={$p}", "操作成功");
    } else {
        js_redirect("index.php?act=class&p={$p}", "操作失败");
    }
}

function hock_course()
{
    $data = [];
    $data = hock_base_list("course");
    return $data;
}

function hock_course_edit()
{
    $data = [];
    $id = intval(get("id")) + 0;
    if ($id > 0) {
        $data['info'] = hock_base_info('course', $id);
    } else {
        //新增
    }
    return $data;
}

function hock_course_edit_do()
{
    $data = [];
    $id = intval(post("id")) + 0;
    $post_data = all(array("course_name" => ""), "post");
    if ($id > 0) {
        $result = db_update(create_update_sql('course', $post_data, $where = "id={$id}", $prefix = ''));
    } else {
        $result = $id = db_insert(create_insert_sql('course', $post_data, $prefix = ''));
    }
    if ($result) {
        get_all_course_hash(true);
        js_redirect("index.php?act=course", "操作成功");
    } else {
        js_redirect("index.php?act=course_edit&id={$id}", "操作失败");
    }
}

function hock_course_del()
{
    $id = get("id");
    $id = explode("-", $id);
    $p = get("p") + 0;
    $result = hock_base_del('course', $id);
    if ($result) {
        get_all_course_hash(true);
        js_redirect("index.php?act=course&p={$p}", "操作成功");
    } else {
        js_redirect("index.php?act=course&p={$p}", "操作失败");
    }
}

function hock_course_manager()
{
    $data = [];
    $data = hock_base_list("teacher_class_course");
    $data['class'] = get_all_class_hash();
    $data['teacher'] = get_all_teacher_hash();
    $data['course'] = get_all_course_hash();
    return $data;
}

function hock_course_manager_edit()
{
    $data = [];
    $id = intval(get("id")) + 0;
    if ($id > 0) {
        $data['info'] = hock_base_info('teacher_class_course', $id);
    } else {
        //新增
        $data['info']['teacher_id'] = 0;
        $data['info']['course_id'] = 0;
        $data['info']['class_id'] = 0;
    }
    $class_list = my_array_unshift(get_all_class_hash(), ["" => "请选择班级"]);
    $attr = array(
        "name" => "class_id",
        "class" => "input w50",
        "data-validate" => "required:请选择班级"
    );
    $data['class'] = create_select_label($class_list, $attr, $data['info']['class_id']);

    $teacher_list = my_array_unshift(get_all_teacher_hash(), ["" => "请选择教师"]);
    $attr = array(
        "name" => "teacher_id",
        "class" => "input w50",
        "data-validate" => "required:请选择教师"
    );
    $data['teacher'] = create_select_label($teacher_list, $attr, $data['info']['teacher_id']);

    $course_list = my_array_unshift(get_all_course_hash(), ["" => "请选择课程"]);
    $attr = array(
        "name" => "course_id",
        "class" => "input w50",
        "data-validate" => "required:请选择课程"
    );
    $data['course'] = create_select_label($course_list, $attr, $data['info']['course_id']);

    $year_list = my_array_unshift(get_all_year_hash(), ["" => "请选择年份"]);
    $attr = array(
        "name" => "year",
        "class" => "input w50",
        "data-validate" => "required:请选择年份"
    );
    $data['year'] = create_select_label($year_list, $attr, $data['info']['year']);
    return $data;
}

function hock_course_manager_edit_do()
{
    $data = [];
    $id = intval(post("id")) + 0;
    $post_data = all(array("teacher_id" => "", "class_id" => "", "course_id" => "", "year" => date("Y", time())), "post");
    if ($id > 0) {
        $result = db_update(create_update_sql('teacher_class_course', $post_data, $where = "id={$id}", $prefix = ''));
    } else {
        $result = $id = db_insert(create_insert_sql('teacher_class_course', $post_data, $prefix = ''));
    }
    if ($result) {
        js_redirect("index.php?act=course_manager", "操作成功");
    } else {
        js_redirect("index.php?act=course_manager_edit&id={$id}", "操作失败");
    }
}

function hock_course_manager_del()
{
    $id = get("id");
    $id = explode("-", $id);
    $p = get("p") + 0;
    $result = hock_base_del('teacher_class_course', $id);
    if ($result) {
        get_all_course_hash(true);
        js_redirect("index.php?act=course_manager&p={$p}", "操作成功");
    } else {
        js_redirect("index.php?act=course_manager&p={$p}", "操作失败");
    }
}
